/**
 * 在调用 new 的过程中会发生以上四件事情：
 * （1）首先创建了一个新的空对象
 * （2）设置原型，将对象的原型设置为函数的 prototype 对象。
 * （3）让函数的 this 指向这个对象，执行构造函数的代码（为这个新对象添加属性）
 * （4）判断函数的返回值类型，如果是值类型，返回创建的对象。如果是引用类型，就返回这个引用类型的对象。
 * */

function myNew() {
    //拿到构造函数
    let args = Array.prototype.slice.call(arguments);
    let fn = args.shift();
    //创建新对象
    let obj = Object.create(fn.prototype)
    let result = fn.apply(obj, args)
    //判断返回对象
    let flag = result && (typeof result === "object" || typeof result === "function");
    return flag ? result : obj;
}

var Fn = function(name, age) {
    this.name = name
    this.age = age
}

Fn.prototype.say = function() {
    console.log('Fn.prototype.say')
}
// 测试
var newObj = myNew(Fn, 'Leo', 18)

console.log(newObj)
newObj.say()